23 #define foreach(x, v) for (typeof (v).begin() x = (v).begin(); x != (v).end(); ++x)
24 #define For(i, a, b) for (int i=(a); i<(b); ++i)
25 #define D(x) cout << #x " is " << x << endl
30 ones
, twos
, threes
, fours
, fives
, sixes
, chance
, three_of_a_kind
,
31 four_of_a_kind
, five_of_a_kind
, short_straight
, long_straight
,
35 int score(turn t
, int c
){
37 for (int i
=0; i
<5; ++i
) times
[t
[i
]]++;
45 return times
[c
+1] * (c
+1);
47 return accumulate(t
, t
+5, 0);
49 for (int i
=1; i
<=6; ++i
) if (times
[i
] >= 3) return accumulate(t
, t
+5, 0);
52 for (int i
=1; i
<=6; ++i
) if (times
[i
] >= 4) return accumulate(t
, t
+5, 0);
55 for (int i
=1; i
<=6; ++i
) if (times
[i
] >= 5) return 50;
58 for (int i
=1; i
<=3; ++i
)
59 if (times
[i
] > 0 && times
[i
+1] > 0 && times
[i
+2] > 0 && times
[i
+3] > 0) return 25;
62 for (int i
=1; i
<=2; ++i
)
63 if (times
[i
] > 0 && times
[i
+1] > 0 && times
[i
+2] > 0 && times
[i
+3] > 0 && times
[i
+4] > 0) return 35;
67 for (int i
=1; i
<=6; ++i
)
68 for (int j
=1; j
<=6; ++j
)
69 if (times
[i
] == 3 && times
[j
] == 2) return 40;
72 printf("Something very bad happened.\n");
81 dp[i][mask] = Best score having matched categories [0..i] and turns <on> on mask.
83 int choice
[13][1 << 13];
87 for (int i
=0; i
<13; ++i
){
88 for (int j
=0; j
<5; ++j
){
89 if (scanf("%d", &turns
[i
][j
]) != 1) return 0;
93 for (int i
=0; i
<13; ++i
)
94 for (int j
=0; j
<(1 << 13); ++j
)
95 dp
[i
][j
] = INT_MIN
, choice
[i
][j
] = -1;
99 for (int t
=0; t
<13; ++t
){
100 dp
[ones
][1 << t
] = score(turns
[t
], ones
);
101 choice
[ones
][1 << t
] = t
;
104 for (int c
=twos
; c
<=full_house
; ++c
){
105 for (int mask
= 0; mask
< (1 << 13); ++mask
){
106 if (__builtin_popcount(mask
) != c
+ 1) continue;
107 for (int t
=0; t
<13; ++t
){
108 int prev_mask
= mask
& ~(1 << t
);
110 int canDo
= dp
[c
-1][prev_mask
] + score(turns
[t
], c
);
111 if (canDo
> dp
[c
][mask
]){
116 if (c
== sixes
&& dp
[c
][mask
] >= 63){
123 //Now find the matching from the computed table
124 //The last state is dp[all_categories][all_turns] = dp[12][11111...1111B]
126 for (int c
=12, mask
= (1 << 13) - 1; c
>= 0; c
--){
127 match
[c
] = choice
[c
][mask
];
128 mask
&= ~(1 << choice
[c
][mask
]);
130 int sum
= 0, bonus
= 0;
131 for (int c
= ones
; c
<= full_house
; ++c
){
132 int s
= score(turns
[match
[c
]], c
);
135 if (c
== sixes
&& sum
>= 63){
140 //assert(sum == dp[12][(1 << 13) - 1]);
141 printf("%d %d\n", bonus
, sum
);